using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;

namespace DLLViewer
{
    public class DecompilerService
    {
        private PEFile _peFile;
        private CSharpDecompiler _decompiler;

        public List<TreeViewItem> LoadAssembly(string filePath)
        {
            _peFile = new PEFile(filePath);
            _decompiler = new CSharpDecompiler(_peFile, new DecompilerSettings
            {
                ThrowOnAssemblyResolveErrors = false,
                UseNestedTypesForNamespaces = true
            });

            var items = new List<TreeViewItem>();

            // 添加命名空间
            var namespaces = _decompiler.TypeSystem.MainModule.TypeDefinitions
                .Select(t => t.Namespace)
                .Where(ns => !string.IsNullOrEmpty(ns))
                .Distinct()
                .OrderBy(ns => ns);

            foreach (var ns in namespaces)
            {
                var nsItem = new TreeViewItem
                {
                    Header = ns,
                    Tag = ns
                };

                // 添加该命名空间下的类型
                var types = _decompiler.TypeSystem.MainModule.TypeDefinitions
                    .Where(t => t.Namespace == ns)
                    .OrderBy(t => t.Name);

                foreach (var type in types)
                {
                    var typeItem = CreateTypeItem(type);
                    nsItem.Items.Add(typeItem);
                }

                items.Add(nsItem);
            }

            // 添加无命名空间的类型
            var noNamespaceTypes = _decompiler.TypeSystem.MainModule.TypeDefinitions
                .Where(t => string.IsNullOrEmpty(t.Namespace))
                .OrderBy(t => t.Name);

            foreach (var type in noNamespaceTypes)
            {
                items.Add(CreateTypeItem(type));
            }

            return items;
        }

        private TreeViewItem CreateTypeItem(ITypeDefinition type)
        {
            var typeItem = new TreeViewItem
            {
                Header = type.Name,
                Tag = type
            };

            // 添加方法
            var methods = type.Methods.Where(m => !m.IsCompilerGenerated()).OrderBy(m => m.Name);
            foreach (var method in methods)
            {
                var methodItem = new TreeViewItem
                {
                    Header = $"{method.Name}({string.Join(", ", method.Parameters.Select(p => $"{p.Type.Name} {p.Name}"))})",
                    Tag = method
                };
                typeItem.Items.Add(methodItem);
            }

            // 添加属性
            var properties = type.Properties.Where(p => !p.IsCompilerGenerated()).OrderBy(p => p.Name);
            foreach (var property in properties)
            {
                var propItem = new TreeViewItem
                {
                    Header = $"{property.Name} {{ {(property.HasGetter ? "get; " : "")}{(property.HasSetter ? "set; " : "")}}}",
                    Tag = property
                };
                typeItem.Items.Add(propItem);
            }

            // 添加字段
            var fields = type.Fields.Where(f => !f.IsCompilerGenerated()).OrderBy(f => f.Name);
            foreach (var field in fields)
            {
                var fieldItem = new TreeViewItem
                {
                    Header = $"{field.Type.Name} {field.Name}",
                    Tag = field
                };
                typeItem.Items.Add(fieldItem);
            }

            return typeItem;
        }

        public string GetCode(object target, string language)
        {
            if (_decompiler == null)
                throw new InvalidOperationException("请先加载程序集");

            var settings = new DecompilerSettings
            {
                ThrowOnAssemblyResolveErrors = false,
                UseNestedTypesForNamespaces = true
            };

            switch (target)
            {
                case string ns when !string.IsNullOrEmpty(ns):
                    return GetNamespaceCode(ns);

                case ITypeDefinition type:
                    return _decompiler.DecompileTypeAsString(type.FullTypeName);

                case IMethod method:
                    return _decompiler.DecompileAsString(method.MetadataToken);

                case IProperty property:
                    return _decompiler.DecompileAsString(property.MetadataToken);

                case IField field:
                    return _decompiler.DecompileAsString(field.MetadataToken);

                default:
                    return "// 不支持的类型";
            }
        }

        private string GetNamespaceCode(string namespaceName)
        {
            var types = _decompiler.TypeSystem.MainModule.TypeDefinitions
                .Where(t => t.Namespace == namespaceName)
                .OrderBy(t => t.Name);

            var sb = new StringBuilder();
            sb.AppendLine($"namespace {namespaceName}");
            sb.AppendLine("{");

            foreach (var type in types)
            {
                var typeCode = _decompiler.DecompileTypeAsString(type.FullTypeName);
                sb.AppendLine(typeCode);
                sb.AppendLine();
            }

            sb.AppendLine("}");
            return sb.ToString();
        }
    }
}
